package com.atguigu.tingshu.search.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import co.elastic.clients.elasticsearch._types.aggregations.Buckets;
import co.elastic.clients.elasticsearch._types.aggregations.LongTermsBucket;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.CompletionSuggestOption;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.Suggestion;
import co.elastic.clients.json.JsonData;
import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.TingShuException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.*;
import com.atguigu.tingshu.model.search.AlbumInfoIndex;
import com.atguigu.tingshu.model.search.AttributeValueIndex;
import com.atguigu.tingshu.model.search.SuggestIndex;
import com.atguigu.tingshu.query.search.AlbumIndexQuery;
import com.atguigu.tingshu.search.repository.AlbumInfoIndexRepository;
import com.atguigu.tingshu.search.repository.SuggestIndexRepository;
import com.atguigu.tingshu.search.service.SearchService;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.atguigu.tingshu.vo.search.AlbumInfoIndexVo;
import com.atguigu.tingshu.vo.search.AlbumSearchResponseVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.suggest.Completion;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;


@Slf4j
@Service
@SuppressWarnings({"all"})
public class SearchServiceImpl implements SearchService {

    @Autowired
    private AlbumInfoIndexRepository albumInfoIndexRepository;

    @Autowired
    private AlbumFeignClient albumFeignClient;
    
    @Autowired
    private UserFeignClient userFeignClient;

    //添加自定义线程池
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    private static final String INDEX_NAME = "albuminfo";

    private static final String SUGGEST_INDEX_NAME = "suggestinfo";

    @Autowired
    private SuggestIndexRepository suggestIndexRepository;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 上架专辑-导入索引库
     * @param albumId
     */
    @Override
    public void upperAlbum(Long albumId) {
        AlbumInfoIndex albumInfoIndex = new AlbumInfoIndex();

        CompletableFuture<AlbumInfo> albumInfoCT = CompletableFuture.supplyAsync(() -> {
            Result albumInfoResult = albumFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult, "专辑信息不存在，专辑id：{}", albumId);
            AlbumInfo albumInfo = (AlbumInfo) albumInfoResult.getData();
            albumInfoIndex.setId(albumId);
            //封装专辑基本数据
            BeanUtils.copyProperties(albumInfo, albumInfoIndex);
            albumInfoIndex.setCreateTime(new Date());
            //封装专辑属性信息
            List<AlbumAttributeValue> albumAttributeValueVoList = albumInfo.getAlbumAttributeValueVoList();
            if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
                List<AttributeValueIndex> attributeValueIndexList = albumAttributeValueVoList.stream().map(albumAttributeValue -> {
                    AttributeValueIndex attributeValueIndex = new AttributeValueIndex();
                    attributeValueIndex.setAttributeId(albumAttributeValue.getValueId());
                    attributeValueIndex.setValueId(albumAttributeValue.getValueId());
                    return attributeValueIndex;
                }).collect(Collectors.toList());
                albumInfoIndex.setAttributeValueIndexList(attributeValueIndexList);
            }
            return albumInfo;
        },threadPoolExecutor);
        CompletableFuture<Void> categoryIdCT = albumInfoCT.thenAcceptAsync((albumInfo) -> {
            //获取基本属性类型
            Long category3Id = albumInfo.getCategory3Id();
            Result<BaseCategoryView> categoryViewResult = albumFeignClient.getCategoryView(category3Id);
            Assert.notNull(categoryViewResult, "分类信息不存在，分类id：{}", category3Id);
            BaseCategoryView baseCategoryView = categoryViewResult.getData();
            albumInfoIndex.setCategory1Id(baseCategoryView.getCategory1Id());
            albumInfoIndex.setCategory2Id(baseCategoryView.getCategory2Id());
        },threadPoolExecutor);

        CompletableFuture<Void> userInfoCT = albumInfoCT.thenAcceptAsync((albumInfo) -> {
            //获取用户信息
            Result<UserInfoVo> userInfoVoResult = userFeignClient.getUserInfoVoById(albumInfo.getUserId());
            Assert.notNull(userInfoVoResult, "用户信息不存在，用户id：{}", albumInfo.getUserId());
            UserInfoVo userInfoVo = userInfoVoResult.getData();
            albumInfoIndex.setAnnouncerName(userInfoVo.getNickname());
        },threadPoolExecutor);
        CompletableFuture<Void> scoreCT = CompletableFuture.runAsync(() -> {
            int num1 = RandomUtil.randomInt(1000, 2000);
            int num2 = RandomUtil.randomInt(500, 1000);
            int num3 = RandomUtil.randomInt(200, 400);
            int num4 = RandomUtil.randomInt(100, 200);
            albumInfoIndex.setPlayStatNum(num1);
            albumInfoIndex.setSubscribeStatNum(num2);
            albumInfoIndex.setBuyStatNum(num3);
            albumInfoIndex.setCommentStatNum(num4);
            BigDecimal bigDecimal1 = new BigDecimal(num4).multiply(new BigDecimal("0.4"));
            BigDecimal bigDecimal2 = new BigDecimal(num3).multiply(new BigDecimal("0.3"));
            BigDecimal bigDecimal3 = new BigDecimal(num2).multiply(new BigDecimal("0.2"));
            BigDecimal bigDecimal4 = new BigDecimal(num1).multiply(new BigDecimal("0.1"));
            BigDecimal hotScore = bigDecimal1.add(bigDecimal2).add(bigDecimal3).add(bigDecimal4);
            albumInfoIndex.setHotScore(hotScore.doubleValue());
        },threadPoolExecutor);
        CompletableFuture.allOf(albumInfoCT,categoryIdCT,userInfoCT,scoreCT).join();
        albumInfoIndexRepository.save(albumInfoIndex);

        //初始化提词器索引库
        this.saveSuggestIndex(albumInfoIndex);
    }

    /**
     * 初始化提词器索引库
     * @param albumInfoIndex
     */
    private void saveSuggestIndex(AlbumInfoIndex albumInfoIndex) {
        SuggestIndex suggestIndex = new SuggestIndex();
        suggestIndex.setId(albumInfoIndex.getId().toString());
        suggestIndex.setTitle(albumInfoIndex.getAlbumTitle());
        suggestIndex.setKeyword(new Completion(new String[]{albumInfoIndex.getAlbumTitle()}));
        suggestIndex.setKeywordPinyin(new Completion(new String[]{PinyinUtil.getPinyin(albumInfoIndex.getAlbumTitle(),"")}));
        suggestIndex.setKeywordSequence(new Completion(new String[]{PinyinUtil.getFirstLetter(albumInfoIndex.getAlbumTitle(),"")}));
        suggestIndexRepository.save(suggestIndex);
    }

    @Override
    public void upperBatchAlbum() {
        for (int i = 0; i < 1602; i++) {
            try {
                this.upperAlbum(i + 1L);
            } catch (Exception e) {
                continue;
            }
        }
    }

    @Override
    public void lowerAlbum(Long albumId) {
        albumInfoIndexRepository.deleteById(albumId);
    }

    @Override
    @SneakyThrows
    public AlbumSearchResponseVo search(AlbumIndexQuery albumIndexQuery) {
        //获取searchRequest
        SearchRequest searchRequest = this.buildDsl(albumIndexQuery);
        log.info("生成的DSL语句：{}",searchRequest);
        //获取searchResponse
        SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(searchRequest, AlbumInfoIndex.class);
        AlbumSearchResponseVo albumSearchResponseVo = this.getResult(searchResponse,albumIndexQuery);
        return albumSearchResponseVo;
    }

    /**
     * 封装对应的结果
     * @param searchResponse
     * @return
     */
    private AlbumSearchResponseVo getResult(SearchResponse<AlbumInfoIndex> searchResponse,AlbumIndexQuery albumIndexQuery) {
        AlbumSearchResponseVo albumSearchResponseVo = new AlbumSearchResponseVo();
        albumSearchResponseVo.setPageNo(albumIndexQuery.getPageNo());
        albumSearchResponseVo.setPageSize(albumIndexQuery.getPageSize());
        long total = searchResponse.hits().total().value();
        Integer pageSize = albumIndexQuery.getPageSize();
        albumSearchResponseVo.setTotal(total);
        albumSearchResponseVo.setTotalPages(total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1);
        List<Hit<AlbumInfoIndex>> hits = searchResponse.hits().hits();
        if(CollectionUtil.isNotEmpty(hits)){
            List<AlbumInfoIndexVo> albumInfoIndexVos = hits.stream().map(hit -> {
                AlbumInfoIndexVo albumInfoIndexVo = BeanUtil.toBean(hit.source(), AlbumInfoIndexVo.class);
                //获取高亮信息
                Map<String, List<String>> highlight = hit.highlight();
                if(CollectionUtil.isNotEmpty(highlight) && highlight.containsKey("albumTitle")){
                    String albumTitle = highlight.get("albumTitle").get(0);
                    if(albumTitle != null){
                        albumInfoIndexVo.setAlbumTitle(albumTitle);
                    }
                }
                return albumInfoIndexVo;
            }).collect(Collectors.toList());
            albumSearchResponseVo.setList(albumInfoIndexVos);
        }
        return albumSearchResponseVo;
    }

    /**
     * 构造dsl获取searchRequest
     * @param albumIndexQuery
     * @return
     */
    private SearchRequest buildDsl(AlbumIndexQuery albumIndexQuery) {
        SearchRequest.Builder resultBuilder = new SearchRequest.Builder();
        resultBuilder.index(INDEX_NAME);
        BoolQuery.Builder allBoolQuery = new BoolQuery.Builder();
        String keyword = albumIndexQuery.getKeyword();
        //构造关键字
        if(StringUtils.isNotBlank(keyword)){
            BoolQuery.Builder keyBoolQuery = new BoolQuery.Builder();
            //标题
            keyBoolQuery.should(s->s.match(t->t.field("albumTitle").query(keyword)));
            //简介
            keyBoolQuery.should(s->s.match(t->t.field("albumIntro").query(keyword)));
            //精确匹配，作家
            keyBoolQuery.should(s->s.term(t->t.field("announcerName").value(keyword)));

            allBoolQuery.must(keyBoolQuery.build()._toQuery());
        }
        //一二三级分类
        if(albumIndexQuery.getCategory1Id() != null){
            allBoolQuery.filter(s->s.term(t->t.field("category1Id").value(albumIndexQuery.getCategory1Id())));
        }
        if(albumIndexQuery.getCategory2Id() != null){
            allBoolQuery.filter(s->s.term(t->t.field("category2Id").value(albumIndexQuery.getCategory2Id())));
        }
        if(albumIndexQuery.getCategory3Id() != null){
            allBoolQuery.filter(s->s.term(t->t.field("category3Id").value(albumIndexQuery.getCategory3Id())));
        }
        //构造nested类型
        List<String> attributeList = albumIndexQuery.getAttributeList();
        if(!CollectionUtils.isEmpty(attributeList)){
            for (String s : attributeList) {
                String[] split = s.split(":");
                if(split != null && split.length == 2){
                    String attributeId = split[0];
                    String valueId = split[1];
                    allBoolQuery.filter(
                            n->n.nested(
                                    p->p.path("attributeValueIndexList")
                                            .query(b->b.bool(f->f
                                                    .filter(ft->ft.term(fv->fv.field("attributeValueIndexList.attributeId").value(attributeId)))
                                                    .filter(ft->ft.term(fv->fv.field("attributeValueIndexList.valueId").value(valueId)))))));
                }

            }
        }
        resultBuilder.query(allBoolQuery.build()._toQuery());
        //分页
        resultBuilder.from((albumIndexQuery.getPageNo() - 1) * albumIndexQuery.getPageSize());
        resultBuilder.size(albumIndexQuery.getPageSize());
        //高亮
        if(StringUtils.isNotEmpty(albumIndexQuery.getKeyword())){
            resultBuilder.highlight(h->h.fields("albumTitle",ht->ht.preTags("<font style='color:red'>").postTags("</font>")));
        }
        //排序
        String order = albumIndexQuery.getOrder();
        //判断参数排序是否提交 提交形式： 排序字段（1：综合 2：播放量 3：发布时间）:排序方式
        if(StringUtils.isNotEmpty(order)){
            String[] split = order.split(":");
            if(split != null && split.length == 2){
                String number = split[0];
                String orderType = split[1];
                String orderField = null;
                switch (number){
                    case "1":
                        orderField = "hotScore";
                        break;
                    case "2":
                        orderField = "playStatNum";
                        break;
                    case "3":
                        orderField = "createTime";
                        break;
                }
                String finalOrderField = orderField;
                resultBuilder.sort(t->t.field(f->f.field(finalOrderField).order("asc".equals(orderType) ? SortOrder.Asc : SortOrder.Desc)));
            }
        }
        //排除字段
        resultBuilder.source(t->t.filter(k->k.excludes("category1Id",
                "category2Id",
                "category3Id",
                "attributeValueIndexList.attributeId",
                "attributeValueIndexList.valueId")));
        return resultBuilder.build();
    }

    @Override
    public List<Map<String, Object>> channel(Long category1Id) {
        List<Map<String,Object>> result = null;
        try{
            Result<List<BaseCategory3>> topBaseCategory3 = albumFeignClient.findTopBaseCategory3(category1Id);
            Assert.notNull(topBaseCategory3, "3级分类信息不存在，1级分类id：{}", category1Id);
            List<BaseCategory3> baseCategory3s = topBaseCategory3.getData();
            Map<Long, BaseCategory3> baseCategory3Map = baseCategory3s.stream().collect(Collectors.toMap(BaseCategory3::getId, v -> v, (k1, k2) -> k1));
            List<Long> category3Ids = baseCategory3s.stream().map(BaseCategory3::getId).collect(Collectors.toList());
            //设置FieldValue
            List<FieldValue> fieldValues = category3Ids.stream().map(FieldValue::of).collect(Collectors.toList());
            //构造请求对象
            SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(s ->
                            s.index(INDEX_NAME)
                                    .query(t -> t.terms(te -> te.field("category3Id").terms(ter -> ter.value(fieldValues))))
                                    .aggregations("category3Agg",
                                            ag -> ag
                                                    .terms(f -> f.field("category3Id").size(10))
                                                    .aggregations("top6Agg", tp -> tp.topHits(th -> th.sort(f -> f.field(tf -> tf.field("hotScore").order(SortOrder.Desc))).size(10))))
                                    .size(0),
                    AlbumInfoIndex.class);
            Aggregate category3Agg = searchResponse.aggregations().get("category3Agg");
            Buckets<LongTermsBucket> buckets = category3Agg.lterms().buckets();
            List<LongTermsBucket> bucketList = buckets.array();
            if(CollectionUtil.isNotEmpty(bucketList)){
                result = bucketList.stream().map(bucket->{
                    long category3Id = bucket.key();
                    Map<String,Object> map = new HashMap<>();
                    BaseCategory3 baseCategory3 = baseCategory3Map.get(category3Id);
                    map.put("baseCategory3",baseCategory3);

                    Aggregate top6Agg = bucket.aggregations().get("top6Agg");
                    List<Hit<JsonData>> hits = top6Agg.topHits().hits().hits();
                    if(CollectionUtil.isNotEmpty(hits)){
                        List<AlbumInfoIndex> albumInfoIndexVos = hits.stream().map(hit -> {
                            JsonData source = hit.source();
                            AlbumInfoIndex albumInfoIndex = JSON.parseObject(source.toString(), AlbumInfoIndex.class);
                            return albumInfoIndex;
                        }).collect(Collectors.toList());
                        map.put("list",albumInfoIndexVos);
                    }
                    return map;
                }).collect(Collectors.toList());
            }
        }catch (Exception e){
            log.error("查询热门专辑信息对接es出现异常");
            throw new RuntimeException(e);
        }
        return result;

    }

    @Override
    public List<String> completeSuggest(String keyword) {
       try{
           SearchResponse<SuggestIndex> searchResponse = elasticsearchClient.search(s->s.index(SUGGEST_INDEX_NAME)
                                          .suggest(su->su.suggesters("mySuggestKeyword",t->t.prefix(keyword).completion(k->k.field("keyword").size(10).skipDuplicates(true)))
                                                         .suggesters("mySuggestPinyin",t->t.prefix(keyword).completion(k->k.field("keywordPinyin").size(10).skipDuplicates(true)))
                                                         .suggesters("mySuggestSequence",t->t.prefix(keyword).completion(k->k.field("keywordSequence").size(10).skipDuplicates(true)))),
                   SuggestIndex.class);
           Set<String> resultSet = new HashSet<>();
           resultSet.addAll(this.getSuggestKeyword("mySuggestKeyword",searchResponse));
           resultSet.addAll(this.getSuggestKeyword("mySuggestPinyin",searchResponse));
           resultSet.addAll(this.getSuggestKeyword("mySuggestSequence",searchResponse));

           if(resultSet != null && resultSet.size() >= 10){
               return new ArrayList<>(resultSet).subList(0,10);
           }
           //不足10条使用match查询
           SearchResponse<AlbumInfoIndex> searchAlbumInfoResponse = elasticsearchClient.search(s->s.index(INDEX_NAME).query(t->t.match(f->f.field("albumTitle").query(keyword))),AlbumInfoIndex.class);
           List<Hit<AlbumInfoIndex>> hits = searchAlbumInfoResponse.hits().hits();
           if(!CollectionUtils.isEmpty(hits)){
               for (Hit<AlbumInfoIndex> hit : hits) {
                   String albumTitle = hit.source().getAlbumTitle();
                   resultSet.add(albumTitle);
                   if(resultSet.size() >= 10){
                       break;
                   }
               }
           }
           return new ArrayList<>(resultSet);
       }catch (Exception e){
           log.error("关键字自动补全对接es异常");
           throw new RuntimeException();
       }

    }

    @Override
    public Map<String, Object> getItem(Long albumId) {
        Map<String,Object> map = new ConcurrentHashMap<>();

        //判断是否存在布隆过滤器
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
        boolean contains = bloomFilter.contains(albumId);
        if(!contains){
            throw new TingShuException(404,"专辑数据不存在");
        }
        CompletableFuture<AlbumInfo> albumCT = CompletableFuture.supplyAsync(() -> {
            Result<AlbumInfo> albumInfoResult = albumFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult, "专辑信息不存在，专辑id：{}", albumId);
            AlbumInfo albumInfo = albumInfoResult.getData();

            map.put("albumInfo", albumInfo);
            return albumInfo;
        },threadPoolExecutor);


        CompletableFuture<Void> baseCategoryViewCT = albumCT.thenAcceptAsync((albumInfo) -> {
            Long category3Id = albumInfo.getCategory3Id();
            Result<BaseCategoryView> categoryViewResult = albumFeignClient.getCategoryView(category3Id);
            Assert.notNull(categoryViewResult, "专辑属性不存在，专辑id：{}", albumId);
            BaseCategoryView baseCategoryView = categoryViewResult.getData();
            map.put("baseCategoryView", baseCategoryView);
        },threadPoolExecutor);

        CompletableFuture<Void> albumStatVoCT = CompletableFuture.runAsync(() -> {
            Result<AlbumStatVo> albumStatVoResult = albumFeignClient.getAlbumStatVo(albumId);
            Assert.notNull(albumStatVoResult, "专辑统计信息不存在，专辑id：{}", albumId);
            AlbumStatVo albumStatVo = albumStatVoResult.getData();
            map.put("albumStatVo", albumStatVo);
        },threadPoolExecutor);

        CompletableFuture<Void> announcerCT = albumCT.thenAcceptAsync((albumInfo) -> {
            Long userId = albumInfo.getUserId();
            Result<UserInfoVo> userInfoVoResult = userFeignClient.getUserInfoVoById(userId);
            Assert.notNull(userInfoVoResult, "用户信息不存在，专辑id：{}", albumId);
            UserInfoVo userInfoVo = userInfoVoResult.getData();
            map.put("announcer", userInfoVo);
        },threadPoolExecutor);

        //等待
        CompletableFuture.allOf(albumCT,albumStatVoCT,baseCategoryViewCT,announcerCT).join();
        return map;
    }

    /**
     * 更新排行榜
     */
    @Override
    public void updateLatelyAlbumRanking() {
        Result<List<BaseCategory1>> allCategory1 = albumFeignClient.findAllCategory1();
        Assert.notNull(allCategory1, "专辑一级分类信息不存在");
        List<BaseCategory1> list = allCategory1.getData();
        if(!CollectionUtils.isEmpty(list)){
            Set<Long> category1Ids = list.stream().map(BaseCategory1::getId).collect(Collectors.toSet());
            for (Long category1Id : category1Ids) {
                String[] rankings = {"hotScore", "playStatNum", "subscribeStatNum", "buyStatNum", "commentStatNum"};
                for (String rank : rankings) {
                    try{
                        SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(s -> s.index(INDEX_NAME)
                                        .query(t -> t.term(f -> f.field("category1Id").value(category1Id)))
                                        .sort(t -> t.field(f -> f.field(rank).order(SortOrder.Desc)))
                                        .size(20),
                                AlbumInfoIndex.class);
                        //保存到redis
                        String key = RedisConstant.RANKING_KEY_PREFIX + category1Id;
                        List<AlbumInfoIndex> albumInfos = searchResponse.hits().hits().stream().map(item -> {
                            AlbumInfoIndex albumInfoIndex = item.source();
                            return albumInfoIndex;
                        }).collect(Collectors.toList());
                        //使用hash结构存储
                        redisTemplate.opsForHash().put(key,rank,albumInfos);
                    }catch (Exception e){
                        log.error("对接es更新一级id排行榜出现错误，一级分类id：{}",category1Id);
                    }
                }
            }
        }

//        elasticsearchClient.search(s->s
//                .index(INDEX_NAME)
//                .query(t->t.term(f->f.field("category1Id"))),AlbumInfoIndex.class)
    }

    @Override
    public List<AlbumInfoIndex> findRankingList(Long category1Id, String dimension) {
        String key = RedisConstant.RANKING_KEY_PREFIX + category1Id;
        Boolean flag = redisTemplate.opsForHash().hasKey(key, dimension);
        if(flag){
            List<AlbumInfoIndex> list = (List<AlbumInfoIndex>)redisTemplate.opsForHash().get(key,dimension);
            return list;
        }
        return List.of();
    }

    /**
     * 获取补全单词结果
     * @param keyword
     * @param searchResponse
     * @return
     */
    private Collection<String> getSuggestKeyword(String suggestKeyword, SearchResponse<SuggestIndex> searchResponse) {
        List<Suggestion<SuggestIndex>> suggestions = searchResponse.suggest().get(suggestKeyword);
        List<String> list = new ArrayList<>();
        for (Suggestion<SuggestIndex> suggestion : suggestions) {
            List<CompletionSuggestOption<SuggestIndex>> options = suggestion.completion().options();
            if(!CollectionUtils.isEmpty(options)){
                list= options.stream().map(item -> {
                    return item.source().getTitle();
                }).collect(Collectors.toList());
            }
        }
        return list;
    }


}
